package com.android.fragmentdemo.defineviews
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class DeOverScrollRecyclerView @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null
) : RecyclerView(context, attributeSet) {

    private var inDownOrUp = true
    private var mAdapter: Adapter<*>? = null
    private var mActionState : ActionState = ActionState.None
    private var firstFlag = true

    init {
        addOnScrollListener(object : OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                Log.d(TAG, "dy0:${dy}")
                if (recyclerView.layoutManager is LinearLayoutManager) {
                    val mLayoutManager = recyclerView.layoutManager as? LinearLayoutManager
                    when (mActionState) {
                        ActionState.PullToLoadMore -> {
                            val lastItemPosition =
                                mLayoutManager?.findLastCompletelyVisibleItemPosition() ?: 0
                            inDownOrUp = ((mAdapter?.itemCount ?: 0) - 1) == lastItemPosition && dy > 0
                        }

                        ActionState.PullToRefresh -> {
                            val firstItemPosition =
                                mLayoutManager?.findFirstCompletelyVisibleItemPosition() ?: 0
                            inDownOrUp = 0 == firstItemPosition && dy < 0
                        }

                        ActionState.PullToRefreshAndLoadMore -> {
                            val lastItemPosition =
                                mLayoutManager?.findLastCompletelyVisibleItemPosition() ?: 0
                            val pullToLoadFlag = ((mAdapter?.itemCount ?: 0) - 1) == lastItemPosition && dy > 0

                            val firstItemPosition =
                                mLayoutManager?.findFirstCompletelyVisibleItemPosition() ?: 0
                            val refreshFlag = 0 == firstItemPosition && dy < 0

                            inDownOrUp = pullToLoadFlag || refreshFlag
                        }

                        else -> {}
                    }
                }
            }

            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
            }
        })
    }

    override fun offsetChildrenVertical(dy: Int) {
        super.offsetChildrenVertical(dy)
        if (firstFlag && ActionState.PullToRefresh == mActionState) {
            inDownOrUp = dy == 0
            Log.d(TAG, "dy1:${dy}")
            firstFlag = false
        }
    }

    fun initAdapter(mAdapter: Adapter<*>) {
        this.mAdapter = mAdapter
    }

    fun setActionState(actionState: ActionState) {
        mActionState = actionState
    }

    fun positionInDownOrUp() = inDownOrUp

    fun resetPosition(inDownOrUp: Boolean) {
        this.inDownOrUp = inDownOrUp
    }

    companion object {
        const val TAG = "DeOverScrollRecyclerView"
    }

    sealed class ActionState {
        data object PullToLoadMore : ActionState()
        data object PullToRefresh : ActionState()
        data object PullToRefreshAndLoadMore : ActionState()
        data object None : ActionState()
    }
}